#ifndef CSTR_INC
#define CSTR_INC

#include "losu.h"
#include "losu_mem.h"

#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CSTR_VERSION "0.1.0"

#define CSTR_INIT_SIZE 128

typedef struct cstr {
  char* data;
  size_t size;  // max size
  size_t len;   // current length
} cstr, *cstr_t;

cstr_t cstr_new(const char* str);
void cstr_free(cstr_t str);
void cstr_concat(cstr_t str1, cstr_t str2);
void cstr_concatstr(cstr_t str1, const char* str2);
void cstr_concatchar(cstr_t str, char c);

cstr_t cstr_new(const char* str) {
  cstr_t s = losu_mem_malloc(NULL, sizeof(cstr));
  s->data = losu_mem_malloc(NULL, strlen(str) + CSTR_INIT_SIZE);
  s->size = CSTR_INIT_SIZE + strlen(str);
  s->len = strlen(str);
  memcpy(s->data, str, strlen(str));
  return s;
}

void cstr_free(cstr_t str) {
  if (!str)
    return;
  losu_mem_free(NULL, str->data);
  losu_mem_free(NULL, str);
}
void cstr_concat(cstr_t str1, cstr_t str2) {
  if (str1 && str2) {
    if (str1->size < str1->len + str2->len) {
      str1->data = losu_mem_realloc(NULL, str1->data,
                                    str1->len + str2->len + CSTR_INIT_SIZE);
      str1->size = str1->len + str2->len + CSTR_INIT_SIZE;
    }
    memcpy(str1->data + str1->len, str2->data, str2->len);
    str1->len += str2->len;
    return;
  }
}

void cstr_concatstr(cstr_t str1, const char* str2) {
  if (str1 && str2) {
    if (str1->size < str1->len + strlen(str2)) {
      str1->data = losu_mem_realloc(NULL, str1->data,
                                    str1->len + strlen(str2) + CSTR_INIT_SIZE);
      str1->size = str1->len + strlen(str2) + CSTR_INIT_SIZE;
    }
    memcpy(str1->data + str1->len, str2, strlen(str2));
    str1->len += strlen(str2);
    return;
  }
}
void cstr_concatchar(cstr_t str, char c) {
  if (str) {
    if (str->size < str->len + 1) {
      str->data = losu_mem_realloc(NULL, str->data, str->len + CSTR_INIT_SIZE);
      str->size = str->len + CSTR_INIT_SIZE;
    }
    str->data[str->len] = c;
    str->len++;
    return;
  }
}

#endif